package com.blog.utils;

import com.blog.pojo.IdentifyCode;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * Copyright (C), 2022
 * Author: 苏大大
 * Date: 2022-05-13 14:36
 * FileName: IdentIfyingCode
 * Description:
 */
public class IdentIfyingCode {

    /**
     * 验证码长度
     */
    @Value("5")
    private static  String codeLength="5";

    /**
     * 验证码字符
     */
    private static final char[] CODE_SEQUENCE = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /**
     * 获取cookie中的uniqueId
     *
     * @param request
     * @return
     */
    private static String getUniqueIdFromCookie(HttpServletRequest request) {
        String uniqueId = "";
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().endsWith("_UNIQUE_ID")) {
                    uniqueId = cookie.getValue();
                    break;
                }
            }
        }
        return uniqueId;
    }

    /**
     * 生成随机码
     *
     * @param num
     * @return
     */
    private static String getIdentifyingCode(int num) {
        Random random = new Random();
        String codeStr = "";
        // 生成验证码
        for (int i = 0; i < num; i++) {
            codeStr += String.valueOf(CODE_SEQUENCE[random.nextInt(36)]);
        }
        return codeStr;
    }

    /**
     * 生成验证码图片
     *
     * @return
     */
    public static IdentifyCode generateIdentifyCode(HttpServletRequest request, int width, int height) {
        Map<String, Object> map = new HashMap<>(2);
        String uniqueId = getUniqueIdFromCookie(request);
        if (StringUtils.isBlank(uniqueId)) {
            uniqueId =System.nanoTime() + RandomStringUtils.randomAlphanumeric(10);
        }
        int num = Integer.valueOf(codeLength);
        //生成随机码
        String capText = getIdentifyingCode(num);
        //redis 缓存存储,用于校验
        // redisClient.setex(getIdentifyingCodePreKey(uniqueId), 180, capText);
        IdentifyCode code=new IdentifyCode();
        code.setImg(img(width, height, num, capText));
        code.setUniqueId(uniqueId);
        code.setCapText(capText);
        return code;
    }


    /**
     * 生成图片
     *
     * @param width
     * @param height
     * @param num
     * @param capText
     * @return
     */
    public static BufferedImage img(int width, int height, int num, String capText) {
        int x = width / (num + 1);
        int fontHeight = height - 2;
        int codeY = height - 4;

        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffImg.createGraphics();
        // 创建一个随机数生成器类
        Random random = new Random();
        // 将图像填充为白色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
        // 创建字体，字体的大小应该根据图片的高度来定
        Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
        // 设置字体
        g.setFont(font);

        // 画边框
        g.setColor(Color.WHITE);
        g.drawRect(0, 0, width - 1, height - 1);
        // 随机产生160条干扰线，使图像中的认证码不易被其他程序探测到
        g.setColor(Color.BLACK);
        for (int i = 0; i < 10; i++) {
            int xx = random.nextInt(width);
            int yy = random.nextInt(height);
            int x1 = random.nextInt(10);
            int y1 = random.nextInt(12);
            g.drawLine(xx, yy, xx + x1, yy + y1);
        }
        // randomCode用于保存随机产生的验证码，以便用户登录后进行验证
        String randomCode = capText;
        int red = 0, green = 0, blue = 0;
        // 随机产生codeCount数字的验证码
        for (int i = 0; i < randomCode.length(); i++) {
            // 产生随机的颜色分量来构造颜色值，这样输出的每位数字的颜色值都将不同
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
            // 用随机产生的颜色将验证码绘制到图像中
            g.setColor(new Color(red, green, blue));
            g.drawString(String.valueOf(randomCode.charAt(i)), (i + 1) * x, codeY);
        }

        return buffImg;
    }

}
